<?php
/**
 * Created by PhpStorm.
 * UsersF: Mloong
 * Date: 2019/2/25
 * Time: 10:10
 */

namespace app\login\service;


use app\common\model\Error;
use app\lib\exception\MysqlErrorException;
use app\lib\exception\ParameterException;
use app\lib\exception\RedisServiceException;
use app\login\model\Account;
use Driver\Cache\Redis;
use think\Db;
use think\Exception;

class identificationService
{

    /**
     * 更新标识码或者ip黑名单的业务逻辑
     * @param $type 类型
     * @param $name 用户名
     * @param $data 表单值，写入到数据库
     * @return Account
     */
    public function addIdentificationOrIp($type,$name,$data,$host)
    {
        $model = new Account();
        # 字符串转为数组
        $identification_arr = explode('%', $data);
        # 数组去重
        $new_identification_arr = array_unique($identification_arr);
        # 数组长度如果大于
        if(count($new_identification_arr) > config('num.max_url_num')){
            throw new ParameterException([
                'msg' => '最多有30个标识码',
            ]);
        }
        if($host !== null){
            # 把host写入对对应账号的记录
            $this->updateHost($model, $name, $host);
        }
        # 数组转字符串
        $result = $this->writeSignToMysqlRedis($new_identification_arr, $name, $type, $model, $data);
        return $result;
    }

    /**
     * @param $new_str 经过处理后新的字符串
     * @param $name 推广方名字
     * @param $type sign或者IP
     * @param $model 模型
     * @param $data 原始的字符串
     * @throws RedisServiceException
     */
    private function writeSignToMysqlRedis($new_str, $name, $type, $model ,$data)
    {
        $update_data = implode('%', $new_str);
        $redis_hash_key = config('redis.account').$name;
        # 同步写入redis
        Redis::hset($redis_hash_key, $type, $update_data);
        try{
            $model->where('name','=',$name)
                ->update([$type=>$update_data]);
        }catch (Exception $exception){
            $error_data = [
                'error_data' => '添加sign失败',
            ];
            Error::addErrorLog($error_data);
            return false;
        }
        return true;
    }

    /**
     * 初始化(获取标识码或者IP的值)
     * @param $type
     * @param $name
     * @return mixed
     */
    public function initializationData($name, $type)
    {
        $model = new Account();
        if($type == 'ip'){
            return $model->where('name','=',$name)
                ->find()
                ->visible(['ip']);
        }
        if($type == 'sign'){
            return $model->where('name','=',$name)
                ->find()
                ->visible(['host', 'sign']);
        }

    }


    public function returnAllUrl($name)
    {
        $sign_str = $this->getSignStr($name,'sign');
        $allUlr = $this->getUrlArr($sign_str,$name);
        return $allUlr;
    }
    # 从缓存中或者MySQL读取sign
    private function getSignStr($name,$type)
    {
        $redis_hash_key = config('redis.account').$name;
        $arr_info = Redis::hget($redis_hash_key);
        if(key_exists($type, $arr_info)){
            $sign_str = $arr_info[$type];
        }else{
            $model = new Account();
            try{
                $arr_info = $model->where('name','=',$name)
                    ->find()
                    ->toArray();
                $sign_str = $arr_info[$type];
            }catch (Exception $e){
                $data = [
                    'error_data' => '尝试添加不存在的from标识',
                ];
                Error::addErrorLog($data);
                return -1;
            }

        }
        return $sign_str;
    }
    # 循环拼接URL
    private function getUrlArr($sign_str,$name)
    {
        $sign_arr = explode('%',$sign_str);
        $allUrlArr = [];
        $num = 1;
        $model = new Account();
        $host = $model->getHost($name);

        foreach ($sign_arr as $value){
            $arr['id'] = $num;
            $arr['url'] = "$host/$name/$value";
            $arr['sign'] = $value;
            array_push($allUrlArr,$arr);
            $num ++;
        }
        return $allUrlArr;
    }
    # 删除标识码或者IP
    public function delSignOrIP($data,$name,$type)
    {
        $result = $this->withRedisMysqlData($data,$name,$type);
        return $result;
    }
    # 把字符串转数组，然后unset要删除的值，然后再转成字符串，同步写入redis和mysql
    private function withRedisMysqlData($data,$name,$type)
    {
        $model = new Account();
        $str = $this->getSignStr($name,$type);
        $arr = explode('%',$str);
        $arr_key = array_search($data,$arr);
        unset($arr[$arr_key]);
        $result = $this->writeSignToMysqlRedis($arr,$name,$type,$model,$data);
        return $result;
    }
    # 更新对应账号的host字段
    private function updateHost($model, $name, $host)
    {
        $model->where('name', '=', $name)
            ->data(['host'=> $host])
            ->update();
        $redis_hash_key = config('redis.account').$name;
        # 同步写入redis
        Redis::hset($redis_hash_key, 'host', $host);
    }
}